﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using StockManagement.Commands;
using StockManagement.Helper;

namespace StockManagement.ViewModels
{
    public class OutwardProductViewModel:BaseViewModel
    {
        ObservableCollection<ProductViewModel> _outwardProductCollection = new ObservableCollection<ProductViewModel>();
        string _purchaser;
        ProductViewModel _productVM;
        DelegateCommand _updateCommand;
        DelegateCommand _discardCommand;
        public event ProductUpdatedDelegate OnOutwardProductUpdated;

        public OutwardProductViewModel(ObservableCollection<ProductViewModel> allProductCollection)
        {
            PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(InwardProductViewModel_PropertyChanged);
            allProductCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(allProductCollection_CollectionChanged);
            foreach (var item in allProductCollection)
            {
                if (item.ProductStatus == Helper.ProductStatus.Outward_ToBeDeliverd)
                    _outwardProductCollection.Add(item);
            }
            _outwardProductCollection.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_outwardProductCollection_CollectionChanged);
            _updateCommand = new DelegateCommand(ExecuteUpdateProductCommand, CanExecuteCommand);
            _discardCommand = new DelegateCommand(ExecuteDiscardCommand, CanExecuteCommand);

            SelectedProduct = _outwardProductCollection.FirstOrDefault();
        }

        void _outwardProductCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (SelectedProduct == null && OutwardProductCollection.Count > 0)
                SelectedProduct = OutwardProductCollection.FirstOrDefault();
        }

        void InwardProductViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "SelectedProduct":
                    InitializeProperties();
                    break;
                default:
                    break;
            }
            UpdateCommand.RaiseCanExecuteChanged();
        }

        void allProductCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                    if (e.NewItems.Count < 1)
                        return;

                    var prod = e.NewItems[0] as ProductViewModel;
                    if (prod == null)
                        return;
                    if (prod.ProductStatus != Helper.ProductStatus.Outward_ToBeDeliverd)
                        return;
                    var prodm = OutwardProductCollection.FirstOrDefault(p => p.ProductID == prod.ProductID);
                    if (prodm != null)
                        return;
                    OutwardProductCollection.Add(prod);
                    if (SelectedProduct == null)
                        SelectedProduct = OutwardProductCollection.FirstOrDefault();
                    break;
            }
            RaiseCommands();
        }
        
        private void RaiseCommands()
        {

            DiscardCommand.RaiseCanExecuteChanged();
            UpdateCommand.RaiseCanExecuteChanged();
        }

        private void InitializeProperties()
        {
            if (_productVM == null)
                return;

            _purchaser = _productVM.Purchaser;
        }

        public ProductViewModel SelectedProduct
        {
            get
            {
                return _productVM;
            }
            set
            {
                _productVM = value;
                OnPropertyChanged("SelectedProduct");
            }
        }

        public string Purchaser
        {
            get { return SelectedProduct == null ? string.Empty : _purchaser; }
            set
            {
                _purchaser = value;
                OnPropertyChanged("Purchaser");
            }
        }

        public DateTime Date
        {
            get { return DateTime.Now; }
        }

        public ObservableCollection<ProductViewModel> OutwardProductCollection
        {
            get
            {
                return _outwardProductCollection;
            }
        }

        public DelegateCommand UpdateCommand
        {
            get
            {
                return _updateCommand;
            }
        }

        public DelegateCommand DiscardCommand
        {
            get { return _discardCommand; }
        }

        private bool CanExecuteCommand(object parameter)
        {
            return (_productVM != null && !string.IsNullOrEmpty(Purchaser.Trim()));
        }

        private void ExecuteUpdateProductCommand(object parameter)
        {
            string strmessage = string.Format("Do you want to mark the product '{0}' as Delivered?", SelectedProduct.ProductName);
            var result = ShowConfirmationMessageBox(strmessage, "Deliver Product");
            if (!result)
                return;

            if (!_productVM.UpdateProduct(UpdateType.Deliver, purchaser: Purchaser))
                return;

            if ((OnOutwardProductUpdated != null) &&
                OnOutwardProductUpdated(_productVM))
                OutwardProductCollection.Remove(_productVM);
        }

        public void UpdateProductProperties(ProductViewModel product)
        {
            product.ProductStatus = Helper.ProductStatus.Delivered;
            product.Consumer = _purchaser;
            product.Date = Date;
            Purchaser = string.Empty;
        }

        private void ExecuteDiscardCommand(object parameter)
        {
            var result = ShowConfirmationMessageBox("Do you want to discard the changes to new product?", "Discard");
            if (!result)
                return;

            InitializeProperties();
            RaiseCommands();
        }
    }
}
